package com.example.mqttclient;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.example.mqttclient.mqtt.MqttService;
import com.example.mqttclient.protocol.AirConditioningMessage;
import com.example.mqttclient.protocol.BoolMessage;
import com.example.mqttclient.protocol.CurtainMessage;
import com.example.mqttclient.protocol.FloatMessage;
import com.example.mqttclient.protocol.GearMessage;
import com.example.mqttclient.protocol.IntMessage;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.google.gson.Gson;
import org.eclipse.paho.client.mqttv3.MqttException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.github.mikephil.charting.charts.LineChart;

public class DevicesDemoActivity extends AppCompatActivity implements MqttService.MqttEventCallBack, CompoundButton.OnCheckedChangeListener {
    private TextView connectState, temperatureValue, humidityValue, pmValue, gasValue, doorStatus;
    private EditText airConditioningValue;
    private MqttService.MqttBinder mqttBinder;
    private String TAG = "DevicesDemoActivity";
    private Switch parlourLightSwitch, curtain_switch, fan_socket_switch, air_conditioning_switch;
    private SeekBar parlourLightGearSeekBar, fanSocketGearSeekBar, curtainGearSeekBar;
    private Map<String, Integer> subscribeTopics = new HashMap<>();
    private static final int GAS_ALARM_NOTIFICATION_ID = 1;
    private static final int GAS_THRESHOLD = 50;// 假设阈值为 50
    private static final long DELAY_TIME = 300; // 延迟时间，单位：毫秒
    private Handler handler = new Handler();
    private Runnable publishRunnable;

    // 保存真实的最后挡位（无论开关状态如何）
    private int parlourLightLastGear = 0;
    private int curtainLastGear = 0;
    private int fanLastGear = 0;

    // 标志位：用于控制SeekBar是否可拖动
    private boolean parlourLightSeekBarEnabled = false;
    private boolean curtainSeekBarEnabled = false;
    private boolean fanSeekBarEnabled = false;
    private LineChart temperatureChart, humidityChart, pmChart;
    private Random random = new Random();
    private static final long UPDATE_INTERVAL = 2000; // 每 2 秒更新一次数据


    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mqttBinder = (MqttService.MqttBinder) iBinder;
            mqttBinder.setMqttEventCallback(DevicesDemoActivity.this);
            if (mqttBinder.isConnected()) {
                connectState.setText("已连接");
                subscribeTopics();
            } else {
                connectState.setText("未连接");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_devices_demo);

        connectState = findViewById(R.id.dev_connect_state);
        Intent mqttServiceIntent = new Intent(this, MqttService.class);
        bindService(mqttServiceIntent, connection, Context.BIND_AUTO_CREATE);

        temperatureValue = findViewById(R.id.temperature_value);
        humidityValue = findViewById(R.id.humidity_value);
        pmValue = findViewById(R.id.pm_value);
        gasValue = findViewById(R.id.gas_value);
        doorStatus = findViewById(R.id.door_status);
        airConditioningValue = findViewById(R.id.air_conditioning_value);

        parlourLightSwitch = findViewById(R.id.parlour_light_switch);
        parlourLightSwitch.setOnCheckedChangeListener(this);
        curtain_switch = findViewById(R.id.curtain_switch);
        curtain_switch.setOnCheckedChangeListener(this);
        fan_socket_switch = findViewById(R.id.fan_socket_switch);
        fan_socket_switch.setOnCheckedChangeListener(this);
        air_conditioning_switch = findViewById(R.id.air_conditioning_switch);
        air_conditioning_switch.setOnCheckedChangeListener(this);

        parlourLightGearSeekBar = findViewById(R.id.parlour_light_gear_seekbar);
        parlourLightGearSeekBar.setEnabled(false); // 初始禁用SeekBar
        parlourLightGearSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (!parlourLightSeekBarEnabled) {
                    // 开关未打开时，阻止用户调节并恢复到0
                    seekBar.setProgress(0);
                    return;
                }

                // 用户真正调节了挡位，记录下来
                parlourLightLastGear = progress;

                // 延迟发布MQTT消息，避免频繁发送
                if (publishRunnable != null) {
                    handler.removeCallbacks(publishRunnable);
                }

                publishRunnable = () -> {
                    try {
                        GearMessage gearMessage = new GearMessage(parlourLightSwitch.isChecked(), progress);
                        mqttBinder.publishMessage("/test/light1", new Gson().toJson(gearMessage));
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                };

                handler.postDelayed(publishRunnable, DELAY_TIME);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        curtainGearSeekBar = findViewById(R.id.curtain_gear_seekbar);
        curtainGearSeekBar.setEnabled(false); // 初始禁用SeekBar
        curtainGearSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (!curtainSeekBarEnabled) {
                    // 开关未打开时，阻止用户调节并恢复到0
                    seekBar.setProgress(0);
                    return;
                }

                // 用户真正调节了挡位，记录下来
                curtainLastGear = progress;

                // 延迟发布MQTT消息，避免频繁发送
                if (publishRunnable != null) {
                    handler.removeCallbacks(publishRunnable);
                }

                publishRunnable = () -> {
                    try {
                        CurtainMessage curtainMessage = new CurtainMessage(curtain_switch.isChecked(), progress);
                        mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(curtainMessage));
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                };

                handler.postDelayed(publishRunnable, DELAY_TIME);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        fanSocketGearSeekBar = findViewById(R.id.fan_socket_gear_seekbar);
        fanSocketGearSeekBar.setEnabled(false); // 初始禁用SeekBar
        fanSocketGearSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (!fanSeekBarEnabled) {
                    // 开关未打开时，阻止用户调节并恢复到0
                    seekBar.setProgress(0);
                    return;
                }

                // 用户真正调节了挡位，记录下来
                fanLastGear = progress;

                // 延迟发布MQTT消息，避免频繁发送
                if (publishRunnable != null) {
                    handler.removeCallbacks(publishRunnable);
                }

                publishRunnable = () -> {
                    try {
                        FloatMessage floatMessage = new FloatMessage((float) progress);
                        mqttBinder.publishMessage("/test/fan1", new Gson().toJson(floatMessage));
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                };

                handler.postDelayed(publishRunnable, DELAY_TIME);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        // 初始化图表
        temperatureChart = findViewById(R.id.temperature_chart);
        humidityChart = findViewById(R.id.humidity_chart);
        pmChart = findViewById(R.id.pm_chart);

        initChart(temperatureChart);
        initChart(humidityChart);
        initChart(pmChart);

        // 开始模拟数据更新
//        startDataUpdate();

    }

    void subscribeTopics() {
        new Thread(() -> {
            try {
                subscribeTopics.put("/test/temp",1);
                subscribeTopics.put("/test/hum",2);
                subscribeTopics.put("/test/pm",3);
                subscribeTopics.put("/test/gas",4);
                subscribeTopics.put("/test/door",5);
                for(Map.Entry<String, Integer> entry:subscribeTopics.entrySet()) {
                    mqttBinder.subscribe(entry.getKey());
                }
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }).start();
    }

    void unSubscribeTopics() {
        new Thread(() -> {
            try {
                for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                    mqttBinder.unSubscribe(entry.getKey());
                }
                subscribeTopics.clear();
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }).start();
    }

    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
        if (!mqttBinder.isConnected()) {
            Toast.makeText(this, "未连接到MQTT服务器，请先连接", Toast.LENGTH_SHORT).show();
            return;
        }
        switch (compoundButton.getId()) {
            case R.id.parlour_light_switch:
                new Thread(() -> {
                    if (mqttBinder != null && mqttBinder.isConnected()) {
                        try {
                            // 开关关闭时发送0档，打开时恢复之前的挡位
                            int gear = isChecked ? parlourLightLastGear : 0;
                            GearMessage gearMessage = new GearMessage(isChecked, gear);
                            mqttBinder.publishMessage("/test/light1", new Gson().toJson(gearMessage));

                            // 更新SeekBar状态和显示
                            runOnUiThread(() -> {
                                try {
                                    parlourLightSeekBarEnabled = isChecked;
                                    parlourLightGearSeekBar.setEnabled(isChecked);
                                    parlourLightGearSeekBar.setProgress(gear);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            });
                        } catch (MqttException e) {
                            e.printStackTrace();
                            mqttBinder.reConnect();
                        }
                    } else {
                        if (mqttBinder != null) {
                            mqttBinder.reConnect();
                        }
                    }
                }).start();
                break;
            case R.id.curtain_switch:
                new Thread(() -> {
                    if (mqttBinder != null && mqttBinder.isConnected()) {
                        try {
                            int gear = isChecked ? curtainLastGear : 0;
                            CurtainMessage curtainMessage = new CurtainMessage(isChecked, gear);
                            mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(curtainMessage));

                            // 更新SeekBar状态和显示
                            runOnUiThread(() -> {
                                try {
                                    curtainSeekBarEnabled = isChecked;
                                    curtainGearSeekBar.setEnabled(isChecked);
                                    curtainGearSeekBar.setProgress(gear);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            });
                        } catch (MqttException e) {
                            e.printStackTrace();
                            mqttBinder.reConnect();
                        }
                    } else {
                        if (mqttBinder != null) {
                            mqttBinder.reConnect();
                        }
                    }
                }).start();
                break;
            case R.id.fan_socket_switch:
                new Thread(() -> {
                    if (mqttBinder != null && mqttBinder.isConnected()) {
                        try {
                            int gear = isChecked ? fanLastGear : 0;
                            // 假设这里应该使用合适的消息类，根据实际情况调整
                            FloatMessage floatMessage = new FloatMessage((float) gear);
                            mqttBinder.publishMessage("/test/fan1", new Gson().toJson(floatMessage));

                            // 更新SeekBar状态和显示
                            runOnUiThread(() -> {
                                try {
                                    fanSeekBarEnabled = isChecked;
                                    fanSocketGearSeekBar.setEnabled(isChecked);
                                    fanSocketGearSeekBar.setProgress(gear);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            });
                        } catch (MqttException e) {
                            e.printStackTrace();
                            mqttBinder.reConnect();
                        }
                    } else {
                        if (mqttBinder != null) {
                            mqttBinder.reConnect();
                        }
                    }
                }).start();
                break;
            case R.id.air_conditioning_switch:
                new Thread(() -> {
                    try {
                        if (isChecked) {
                            String json = new Gson().toJson(new AirConditioningMessage(true, Float.parseFloat(airConditioningValue.getText().toString())));
                            Log.d(TAG, "publish:" + json);
                            mqttBinder.publishMessage("/test/airConditioning", json);
                        } else {
                            String json = new Gson().toJson(new AirConditioningMessage(false, Float.parseFloat(airConditioningValue.getText().toString())));
                            Log.d(TAG, "publish:" + json);
                            mqttBinder.publishMessage("/test/airConditioning", json);
                        }
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                }).start();
                break;
        }
    }

    @Override
    public void onConnectSuccess() {
        subscribeTopics();
        connectState.setText("已连接");
    }

    @Override
    public void onConnectError(String error) {
        Log.d(TAG, "onConnectError: " + error);
        connectState.setText("未连接");
        subscribeTopics.clear();
    }

    @Override
    public void onDeliveryComplete() {
        Log.d(TAG, "publish ok");
    }

    @Override
    public void onMqttMessage(String topic, String message) {
        Log.d(TAG, "onMqttMessage, topic:" + topic + " message length:" + message.length() + " message:" + message);
        Gson gson = new Gson();
        switch (subscribeTopics.get(topic)) {
            case 1:
                runOnUiThread(() -> {
                    float newTemperature = gson.fromJson(message.trim(), FloatMessage.class).value;
                    temperatureValue.setText(String.valueOf(newTemperature));
                    updateChart(temperatureChart, newTemperature);
                });
                break;
            case 2:
                runOnUiThread(() -> {
                    int newHumidity = gson.fromJson(message.trim(), IntMessage.class).value;
                    humidityValue.setText(String.valueOf(newHumidity));
                    updateChart(humidityChart, newHumidity);
                });
                break;
            case 3:
                runOnUiThread(() -> {
                    int newPm = gson.fromJson(message.trim(), IntMessage.class).value;
                    pmValue.setText(String.valueOf(newPm));
                    updateChart(pmChart, newPm);
                });
                break;
            case 4:
                runOnUiThread(() -> {
                    try {
                        int gasConcentration = gson.fromJson(message.trim(), IntMessage.class).value;
                        // 更新UI显示气体浓度
                        if (gasValue != null) {
                            gasValue.setText(String.valueOf(gasConcentration));
                        }
                        // 检查阈值并发送警告
                        if (gasConcentration > GAS_THRESHOLD) {
                            sendGasAlarmNotification(gasConcentration);
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "解析气体浓度消息出错: " + e.getMessage());
                    }
                });
                break;
            case 5:
                runOnUiThread(() -> {
                    String status = gson.fromJson(message.trim(), BoolMessage.class).value ? "开" : "关";
                    doorStatus.setText(status);
                });
                break;
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        if (mqttBinder.isConnected()) {
            connectState.setText("已连接");
            subscribeTopics();
        } else {
            connectState.setText("未连接");
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        unSubscribeTopics();
    }

    @Override
    protected void onDestroy() {
        unbindService(connection);
        super.onDestroy();
    }

    private void sendGasAlarmNotification(int gasConcentration) {
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        Intent intent = new Intent(this, DevicesDemoActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, MyApplication.ALARM_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle("可燃气体报警")
                .setContentText("当前可燃气体浓度为 " + gasConcentration + "，已超过安全阈值！")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
            builder.setLights(0xFFFF0000, 3000, 3000);
        }

        Notification notification = builder.build();
        notificationManager.notify(GAS_ALARM_NOTIFICATION_ID, notification);
    }

    private void initChart(LineChart chart) {
        chart.getDescription().setEnabled(false);
        chart.animateX(1000);

        LineData data = new LineData();
        LineDataSet dataSet = new LineDataSet(null, "数据");
        dataSet.setColor(Color.BLUE);
        dataSet.setValueTextColor(Color.BLUE);
        data.addDataSet(dataSet);
        chart.setData(data);
    }

//    private void startDataUpdate() {
//        handler.postDelayed(new Runnable() {
//            @Override
//            public void run() {
//                // 模拟温度数据
//                float temperature = (float) (random.nextDouble() * 30 + 10); // 10 - 40 度
//                temperatureValue.setText(String.valueOf(temperature));
//                updateChart(temperatureChart, temperature);
//
//                // 模拟湿度数据
//                int humidity = random.nextInt(100); // 0 - 100%
//                humidityValue.setText(String.valueOf(humidity));
//                updateChart(humidityChart, humidity);
//
//                // 模拟 PM2.5 数据
//                int pm = random.nextInt(200); // 0 - 200
//                pmValue.setText(String.valueOf(pm));
//                updateChart(pmChart, pm);
//
//                // 继续下一次更新
//                handler.postDelayed(this, UPDATE_INTERVAL);
//            }
//        }, UPDATE_INTERVAL);
//    }

    private void updateChart(LineChart chart, float value) {
        LineData chartData = chart.getData();
        LineDataSet dataSet = (LineDataSet) chartData.getDataSetByIndex(0);
        dataSet.addEntry(new Entry(dataSet.getEntryCount(), value));
        chartData.notifyDataChanged();
        chart.notifyDataSetChanged();
        chart.invalidate();
    }
}